﻿using System;
using Sustainalytics.Reporting.Framework;
using Foxit.PDF.PageElements;
using Foxit.PDF;

namespace Sustainalytics.Governance.Reporting
{
    public class FinalSection: PdfReportSectionGenerator
    {
        const float TermTitleFontSize = 16f;
        const float TermTitleHeight = 22f;
        
        public override void ComposeSectionContent()
        {
            const string sectionTitle = "Glossary of Terms";
            const float titleFontSize = 16f;
            const float sectionTitleHeight = 22f;
            const float top = 20.0f;

            var width = _report.PageMaxWidth;
            var height = _report.PageMaxHeight - 25f;

            var table = GetDefaultTable(_report.LeftMargin, top, width, height);


            table.Columns.Add(width);

            var row = table.Rows.Add(sectionTitleHeight);


            var text = string.Format("<p><font color='FFFFFF'><b>{0}</b></font></p>", sectionTitle);
            var cell = row.Cells.Add(new FormattedTextArea(text, 5f, 1f, width, titleFontSize + 2f, Fonts.CalibriFontFamily, titleFontSize, false));
            cell.BackgroundColor = Colors.SectionColor;
            cell.VAlign = VAlign.Center;

            row = table.Rows.Add(EmptyRowHeight);
            row.Cells.Add(string.Empty);

            AddScoresTerm(table, width);
            AddOutlookTerm(table, width);

            row = table.Rows.Add(EmptyRowHeight*3);
            row.Cells.Add(string.Empty);

            AddDisclaimer(table, width);

            do
            {
                var page = _report.NewPage();
                _report.Pages.Add(page);
                page.Elements.Add(table);
                table = table.GetOverflowRows();

            } while (table != null);
        }

        private void AddTerm(Table table, float width, string title, string description)
        {
            var style = new FormattedTextAreaStyle(Fonts.CalibriLightFontFamily, 8f, false)
            {
                Paragraph = { Align = TextAlign.Justify, Indent = 0, SpacingAfter = 0, AllowOrphanLines = false }
            };

            var row = table.Rows.Add(TermTitleHeight);
            var cell = row.Cells.Add(
                new Label(title, 0.0f, 0.0f, width,
                    TermTitleFontSize + 2f, Fonts.CalibriBold, TermTitleFontSize));
            cell.Border.Bottom.LineStyle = LineStyle.Solid;
            cell.Border.Bottom.Width = 1.5f;
            cell.Border.Bottom.Color = RgbColor.Black;

            var formattedTextArea = new FormattedTextArea(description, 0.0f, 5.0f, width, 500f, style);
            var textAreaHeight = formattedTextArea.GetRequiredHeight() + 5f;

            formattedTextArea = new FormattedTextArea(description, 0.0f, 5.0f, width, textAreaHeight, style);

            row = table.Rows.Add(textAreaHeight);
            row.Cells.Add(formattedTextArea);

            row = table.Rows.Add(EmptyRowHeight);
            row.Cells.Add(string.Empty);
        }

        private void AddScoresTerm(Table table, float width)
        {
            const string title = "Scores";
            const string description = 
                "<p>All scores are on a scale from zero to 100, with zero representing a strongly negative assessment, 50 representing “neutral” assessment, and 100 representing a strongly positive assessment of the company on the dimension. Scores are applied at the indicator level, at the Key Corporate Governance Issue level, and at the overall company level.</p>" +
                "<p></p>" +
                "<p><b>Indicator scores</b></p>" +
                "<p>Indicators are scored on the basis of the underlying data elements enumerated in the bulleted items captured for each indicator. These elements are combined by formula to determine the indicator score, taking into account interactions among the elements.</p>" +
                "<p></p>" +
                "<p><b>Key Corporate Governance Issue and overall scores</b></p>" +
                "<p>Key Issue scores are scored, in general, as a weighted average of the underlying indicators contained within that Key Issue. The overall score is, in general, a weighted average of the Key Corporate Governance Issue scores.</p>"+
                "<p></p>";

            AddTerm(table, width, title, description);
        }

        private void AddOutlookTerm(Table table, float width)
        {
            const string title = "Outlook";
            const string description =
                "<p>The Outlook reflects our qualitative judgment on the overall trajectory of the company’s performance with respect to a Key Corporate Governance Issue or overall. This judgment takes into account both recent improvements and future expectations along the issue and is generally assessed over a multi-year timeframe." +
                "<p></p>";

            AddTerm(table, width, title, description);

            const string positive = 
                "<p>Positive outlook reflects corporate governance practices that suggest strengthening of corporate governance performance, or the persistence of strong performance.</p>" +
                "<p></p>";
            const string neutral = 
                "<p>Neutral outlook reflects corporate governance practices that do not lead to a strong judgment either way regarding the trajectory or prospects for corporate governance performance.</p>" +
                "<p></p>";
            const string negative = 
                "<p>Negative outlook reflects corporate governance practices that suggest weakening of corporate governance performance, or the persistence of poor governance performance.</p>" +
                "<p></p>";

            const float radius = 14f;
            const float bulletHeight = (radius*2) + 20f;
            const float height = bulletHeight * 3;

            var style = new FormattedTextAreaStyle(Fonts.CalibriLightFontFamily, 8f, false)
            {
                Paragraph = { Align = TextAlign.Justify, Indent = 0, SpacingAfter = 0, AllowOrphanLines = false }
            };

            var subtable = GetDefaultTable(0.0f, 0.0f, width, height);

            subtable.Columns.Add(width*0.1f);
            subtable.Columns.Add(width*0.9f);

            var row = subtable.Rows.Add(bulletHeight);
            row.Cells.Add(new BulletOutlook
            {
                Top = 0.0f,
                Left = bulletHeight / 2 - radius,
                Radius = radius,
                Value = 1
            });

            var formattedTextArea = new FormattedTextArea(positive, 0.0f, 5.0f, width * 0.9f, 100f, style);
            var textAreaHeight = formattedTextArea.GetRequiredHeight() + 5f;
            formattedTextArea = new FormattedTextArea(positive, 0.0f, 5.0f, width * 0.9f, textAreaHeight, style);
            row.Cells.Add(formattedTextArea);


            row = subtable.Rows.Add(bulletHeight);
            row.Cells.Add(new BulletOutlook
            {
                Top = 0.0f,
                Left = bulletHeight / 2 - radius,
                Radius = radius,
                Value = 0
            });

            formattedTextArea = new FormattedTextArea(neutral, 0.0f, 5.0f, width * 0.9f, 100f, style);
            textAreaHeight = formattedTextArea.GetRequiredHeight() + 5f;
            formattedTextArea = new FormattedTextArea(neutral, 0.0f, 5.0f, width * 0.9f, textAreaHeight, style);
            row.Cells.Add(formattedTextArea);


            row = subtable.Rows.Add(bulletHeight);
            row.Cells.Add(new BulletOutlook
            {
                Top = 0.0f,
                Left = bulletHeight / 2 - radius,
                Radius = radius,
                Value = -1
            });

            formattedTextArea = new FormattedTextArea(negative, 0.0f, 5.0f, width * 0.9f, 100f, style);
            textAreaHeight = formattedTextArea.GetRequiredHeight() + 5f;
            formattedTextArea = new FormattedTextArea(negative, 0.0f, 5.0f, width * 0.9f, textAreaHeight, style);
            row.Cells.Add(formattedTextArea);

            subtable.Height = subtable.GetRequiredHeight();

            row = table.Rows.Add(subtable.Height);
            row.Cells.Add(subtable);
        }

        private void AddDisclaimer(Table table, float width)
        {
            const string title = "Disclaimer";
            const float fontSize = 9;
            var style = new FormattedTextAreaStyle(Fonts.CalibriLightFontFamily, 8f, false)
            {
                Paragraph = { Align = TextAlign.Justify, Indent = 0, SpacingAfter = 0, AllowOrphanLines = false }
            };

            var copyright1 = $"Copyright ©{DateTime.UtcNow.Year} Sustainalytics. All rights reserved.";

            var row = table.Rows.Add(fontSize);
            row.Cells.Add(new Label(title, 0.0f, 0.0f, width,
                    fontSize + 2f, Fonts.CalibriBold, fontSize));

            row = table.Rows.Add(fontSize);
            row.Cells.Add("");

            row = table.Rows.Add(fontSize);
            row.Cells.Add(new Label(copyright1, 0.0f, 0.0f, width,
                    fontSize + 2f, Fonts.CalibriBold, fontSize - 1));


            var disclaimer = "<p>The ownership and all intellectual property rights to this publication/report and the information contained herein are vested exclusively in Sustainalytics and/or its suppliers. Unless otherwise expressly agreed in writing between you and Sustainalytics, you will not be permitted to use this information otherwise than for internal use, nor will you be permitted to reproduce, disseminate, comingle, create derivative works, furnish in any manner, make available to third parties or publish this publication/report, parts hereof or the information contained herein in any form or in any manner, be it electronically, mechanically, through photocopies, recordings.  The information on which this publication/report is based on reflects the situation as on the date of its elaboration. Such information has – fully or partially – been derived from third parties and is therefore subject to continuous modification. " +
                "THE INFORMATION HEREIN IS PROVIDED SOLELY FOR INFORMATIONAL PURPOSES AND THEREFORE ARE NOT AN OFFER TO BUY OR SELL A SECURITY. NEITHER SUSTAINALYTICS NOR ALL ITS THIRD-PARTY SUPPLIERS PROVIDE INVESTMENT ADVICE (AS DEFINED IN THE APPLICABLE JURISDICTION) OR ANY OTHER FORM OF (FINANCIAL) ADVICE AND NOTHING WITHIN THIS PUBLICATION/REPORT CONSTITUTES SUCH ADVICE. SUSTAINALYTICS OBSERVES THE GREATEST POSSIBLE CARE IN USING INFORMATION, HOWEVER THE INFORMATION IS PROVIDED “AS IS” AND NEITHER SUSTAINALYTICS NOR ITS SUPPLIERS ACCEPT ANY LIABILITY FOR DAMAGE ARISING FROM THE USE OF THIS PUBLICATION/REPORT OR INFORMATION CONTAINED HEREIN IN ANY MANNER WHATSOEVER. MOREOVER, SUSTAINALYTICS AND ALL ITS THIRD-PARTY SUPPLIERS DISCLAIM ANY AND ALL WARRANTIES AND REPRESENTATIONS, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTIES OF MERCHANTIBILITY, COMPLETENESS, ACCURACY OR FITNESS FOR A PARTICULAR PURPOSE.</p>";

            var formattedTextArea = new FormattedTextArea(disclaimer, 0.0f, 0.0f, width, 500f, style);
            var textAreaHeight = formattedTextArea.GetRequiredHeight() + 5f;
            formattedTextArea = new FormattedTextArea(disclaimer, 0.0f, 0.0f, width, textAreaHeight, style);

            row = table.Rows.Add(textAreaHeight);
            row.Cells.Add(formattedTextArea);

            row = table.Rows.Add(fontSize);
            row.Cells.Add(string.Empty);


            disclaimer = "<p>This publication/report may contain proprietary information from third parties (Third Party Data) and here you can find additional terms and conditions imposed by the following Third Party Data providers regarding the use of their data:</ p>";
            formattedTextArea = new FormattedTextArea(disclaimer, 0.0f, 0.0f, width, 500f, style);
            textAreaHeight = formattedTextArea.GetRequiredHeight() + 5f;
            formattedTextArea = new FormattedTextArea(disclaimer, 0.0f, 0.0f, width, textAreaHeight, style);

            row = table.Rows.Add(textAreaHeight);
            row.Cells.Add(formattedTextArea);
            row = table.Rows.Add(fontSize);
            row.Cells.Add(string.Empty);



            const string text = "www.sustainalytics.com/legal-disclaimers";
            var font = Fonts.CalibriBold;

            // Create the link's label
            var label = new Label(text, 0.0f, 0.0f, width, 10f, font, 8f, new RgbColor(240, 171, 0));

            // Set the action then create the link
            var action = new UrlAction("www.sustainalytics.com/legal-disclaimers");
            var link = new Link(0, 0, font.GetTextWidth(text, 8), 20, action);

            // Add the label and the link to the page
            var elements = new Group();
            elements.Add(label);
            elements.Add(link);

            row = table.Rows.Add(fontSize);
            row.Cells.Add(elements);
        }
    }
}
